//! Result 枚举示例
//!
//! Result<T, E> 枚举用于处理可能失败的操作，它有两个变体：
//! - Ok(T): 表示操作成功，包含结果值
//! - Err(E): 表示操作失败，包含错误信息
//!
//! # 错误处理使用场景总结
//!
//! | 使用场景 | 方法 | 说明 |
//! |---------|------|------|
//! | 基础错误处理 | match 表达式 | 最基础的错误处理方式，显式处理成功和失败情况 |
//! | 简化单路径处理 | if let 语句 | 当只关心成功或失败其中一种情况时使用 |
//! | 快速原型或测试 | unwrap/expect | 直接获取值，出错时会 panic，适用于原型或测试代码 |
//! | 提供默认值 | unwrap_or/unwrap_or_else | 失败时返回默认值而不是 panic |
//! | 转换结果值 | map/map_err | 对成功值或错误值进行转换，返回新的 Result |
//! | 错误传播 | ? 操作符 | 在函数中遇到错误时立即返回，将错误传递给调用者 |
//! | 组合操作 | and_then | 链式调用，前一个 Result 成功时才执行下一个操作 |
//!
//! 在实际应用中，应该根据具体场景选择合适的错误处理方式：
//! - 对于可恢复的错误，使用 Result 类型
//! - 对于不可恢复的错误，使用 panic! 宏
//! - 对于可能没有值的情况，使用 Option 类型而不是 Result

/// Result 基础用法
pub fn result_basics() {
    // 定义可能失败的函数
    fn divide(dividend: f64, divisor: f64) -> Result<f64, String> {
        if divisor == 0.0 { Err(String::from("除数不能为零")) } else { Ok(dividend / divisor) }
    }

    // 使用 Result
    let result1 = divide(10.0, 2.0);
    let result2 = divide(10.0, 0.0);

    println!("Result 基础示例:");
    println!("10 / 2 = {:?}", result1);
    println!("10 / 0 = {:?}", result2);
}

/// 处理 Result 值
pub fn handling_result() {
    fn divide(dividend: f64, divisor: f64) -> Result<f64, String> {
        if divisor == 0.0 { Err(String::from("除数不能为零")) } else { Ok(dividend / divisor) }
    }

    let result = divide(10.0, 2.0);

    // 使用 match 处理 Result
    match result {
        Ok(value) => println!("结果是: {}", value),
        Err(e) => println!("错误: {}", e),
    }

    // 使用 if let 简化处理
    if let Ok(value) = divide(20.0, 4.0) {
        println!("20 / 4 = {}", value);
    }
}

/// Result 的常用方法
pub fn result_methods() {
    fn divide(dividend: f64, divisor: f64) -> Result<f64, String> {
        if divisor == 0.0 { Err(String::from("除数不能为零")) } else { Ok(dividend / divisor) }
    }

    let success_result: Result<i32, &str> = Ok(10);
    let error_result: Result<i32, &str> = Err("出错了");

    println!("Result 方法示例:");

    // 使用 is_ok 和 is_err
    println!("success_result is ok: {}", success_result.is_ok());
    println!("error_result is err: {}", error_result.is_err());

    // 使用 unwrap 和 expect
    println!("success_result unwrap: {}", success_result.unwrap());
    println!("success_result expect: {}", success_result.expect("操作失败"));

    // 使用 unwrap_or 提供默认值
    println!("error_result unwrap_or: {}", error_result.unwrap_or(0));

    // 使用 map 转换成功值
    let mapped = success_result.map(|x| x * 2);
    println!("success_result map: {:?}", mapped);

    // 使用 map_err 转换错误值
    let mapped_err = error_result.map_err(|e| format!("错误: {}", e));
    println!("error_result map_err: {:?}", mapped_err);
}

/// 传播错误
pub fn propagating_errors() -> Result<String, String> {
    fn divide(dividend: f64, divisor: f64) -> Result<f64, String> {
        if divisor == 0.0 { Err(String::from("除数不能为零")) } else { Ok(dividend / divisor) }
    }

    // 使用 ? 操作符传播错误
    let result = divide(10.0, 2.0)?; // 如果出错，立即返回 Err
    Ok(format!("结果是: {}", result))
}

/// 使用 ? 操作符简化错误处理
pub fn using_question_mark() {
    fn divide(dividend: f64, divisor: f64) -> Result<f64, String> {
        if divisor == 0.0 { Err(String::from("除数不能为零")) } else { Ok(dividend / divisor) }
    }

    fn calculate() -> Result<f64, String> {
        let a = divide(10.0, 2.0)?; // 5.0
        let b = divide(a, 2.0)?; // 2.5
        Ok(b)
    }

    match calculate() {
        Ok(result) => println!("计算结果: {}", result),
        Err(e) => println!("计算错误: {}", e),
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_result_basics() {
        result_basics();
    }

    #[test]
    fn test_handling_result() {
        handling_result();
    }

    #[test]
    fn test_result_methods() {
        result_methods();
    }

    #[test]
    fn test_propagating_errors() {
        let result = propagating_errors();
        assert!(result.is_ok());
    }

    #[test]
    fn test_using_question_mark() {
        using_question_mark();
    }
}
